<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>

<title>Translation Helper by apqoo</title>

<style type="text/css">
  html, body { padding:10px; width:1000px; overflow:hidden; }
  body, input, textarea { font-family:arial,serif; font-size:15px; }
  textarea { width:400px; height:250px; overflow:scroll; padding:5px; margin-right:5px; }
  .titlespan { width:400px; display:inline-block; padding:3px; }
  input[type=button] { padding:5px 8px; }
</style>

<script type="text/javascript" src="AIRAliases.js" ></script>
<script type="text/javascript" src="prototype.js"></script>

<script type="text/javascript"> 

  var inputFolder = "resource-input";
  var outputFolder = "resource-output";
  
  var translationServiceURL = "http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&langpair=zh|en&q=";
  var httpReferer = "http://code.google.com/p/dn-translation/";

  var filesForTranslation = [];
  var source_text = "";
  var translated_text = "";
  var strings = [];
  var strings_translated = [];
  var stringsSize = 0;
  var extractMethod = 0;
  var translationProgress = 0;
  var specialChars = ['<','>','/','=','%','$','#','{','}',':','[',']','-','+','.','^','\\','\"','\'','\n']; 
  var specialCharsSize = specialChars.size();
  var filesList = [];
  var currentFileIdx = -1;
  var currentFileName = "";
  var numTransReqs = 0;

  Event.observe(window, 'load', function(){
    
    air.trace('Translation Helper by apqoo');
       
    $('input-run').observe('click', runClick);
    
    searchFiles();

  }); 
  
  function searchFiles(){
    
    currentFileIdx = -1;
    
    var dir = air.File.applicationDirectory.resolvePath(inputFolder);
    filesList = dir.getDirectoryListing();
    
    //for(var i=0; i<filesList.length; i++){
    //  air.trace(filesList[i].name);
    //}
    
    filesList = $A(filesList).findAll(function(e){
      return e.name.match(/.xml$/); 
    });
    
    var s = 'Number of XML files in input folder: ' + filesList.length;
    s += '\n\nWarning: Files in input folder will be *deleted* once they have been successfully translated.';
    
    $('text-log-overall').update(s);
    
  }

  function callTranslationService(sourceText, callback){
    
    sourceText = customEncode(sourceText);
    
    var loader = new air.URLLoader();
    var request = new air.URLRequest(translationServiceURL+sourceText);
    
    //var refererHeader = new air.URLRequestHeader('Referer', httpReferer);
    //request.requestHeaders.push(refererHeader);
    
    loader.addEventListener(air.Event.COMPLETE, function(event){

      var loader = air.URLLoader(event.target);      
      var r = loader.data.evalJSON();
      
      if(r.responseStatus == 200){
        
        var t = r.responseData.translatedText;
        t = customDecode(t);
        callback(t);
        
      } else {
        
        air.trace('Server Error:');
        air.trace(' Status: ' + r.responseStatus);
        air.trace(' Details: ' + r.responseDetails);
      }
      
    });

    try {
      
      loader.load(request);
      
    } catch(e) {
      
      air.trace('Error:');
      air.trace(e);
    }

  }
  
  function callTranslationService_old(sourceText, callback){
    
    sourceText = customEncode(sourceText);
    
    new Ajax.Request(translationServiceURL+sourceText, {
      method: 'get',
      onSuccess: function(response) {
        var t = response.responseText.evalJSON().responseData.translatedText;
        t = customDecode(t);
        callback(t);
      },
      onError: function(response) {
        air.trace('Translation Error');
        air.trace(Object.inspect(response.responseText));
      }
    });
  }
  
  function log(s){
    $('text-log').value += s + "\n";
    $('text-log').scrollTop = $('text-log').scrollHeight;
  }
  
  function clearlog(){
    $('text-log').value = "";
  }

  function extractAll(){
    
      clearlog();
      log('Extracting text...\n');
      
      extractMethod = ($('extract-method-0').checked)? 0 : 1;
      strings = [];
      extractText();
      
      strings.each(function(e){ 
        log(e+"\n"); 
      });
      
      log('Found ' + strings.length + ' translatable strings.');
      
  }
  
  function extractText(){
    
    if(extractMethod==0){
      
      //var pattern = /<\!\[CDATA\[(.*)\]\]>/m;
      var pattern = /<\!\[CDATA\[([\s\S]*?)\]\]>/m;
      source_text.scan(pattern, function(match){
        var s = match[1];
        strings.push(s);
      });    
    
    } else {
      
      var pattern = /[\u4E00-\u9FFF]+/g;
      strings = source_text.match(pattern);
    }
  }
  
  function customEncode(s){
    
    for(var i=0; i<specialCharsSize; i++){
      s = s.gsub(specialChars[i], 'xy'+i+'z');
    }
    return s;
  }

  function customDecode(s){
        
    for(var i=0; i<specialCharsSize; i++){
      s = s.gsub('xy'+i+'z', specialChars[i]);
    }        
    return s;
  }   
 
  function translateAll(){
    
    clearlog();
    log('Starting translation...\n');
    
    translationProgress = 0;
    stringsSize = strings.size();
    strings_translated = [];
    
    doTranslation();
    
  }
  
  function doTranslation(){
    
    if(translationProgress < stringsSize){
      
      var s = strings[translationProgress];
      log('Original: '+s);
      
      callTranslationService(s, function(r) {
        strings_translated.push(r);
        log('Translation: ' + r + "\n");
        doTranslation();
      });
            
      updateProgressDisplay();
      translationProgress++;
      
    } else {
      log('Translated ' + strings_translated.size() + ' strings.');
      replaceAll();
    }
    
  }
  
  function updateProgressDisplay(){
    
    var s = 'Translation in progress...\n\n';
    s += 'Current file:\n ' + currentFileName + '\n\n';
    s += 'Current file progress:\n ' + (translationProgress+1) + ' / ' + stringsSize + '\n\n';
    s += 'Overall progress:\n ' + (currentFileIdx+1) + ' / ' + filesList.length + '\n\n';
    s += 'Number of translation requests: ' + (++numTransReqs);
    
    $('text-log-overall').update(s);
    
  }
  
  function replaceAll(){
    
    var s = $('text-source').value; 
    
    for(var i=0; i<strings_translated.size(); i++){
      s = s.sub(strings[i], strings_translated[i]);
    }
    
    //$('text-log').value = s;
    translated_text = s;
    
    saveCurrentFile();
  }
  
  function runClick(){
    
    if(currentFileIdx != -1){
      searchFiles();
    }
     
    processNextFile();
    
  }
  
  function runTranslation(){
    extractAll();
    translateAll();
  }
  
  function readFile(filename){
    
    var str = "";
    
    try {
      
      var file = new air.File(filename);
      var stream = new air.FileStream();
      stream.open(file, air.FileMode.READ);
      
      if(stream.bytesAvailable == 0){
        air.trace('Error: Size of file ' + file.name + ' is 0 bytes');
      }
      
      str = stream.readUTFBytes(stream.bytesAvailable);
      stream.close();
      
    } catch(e){
      air.trace('File Read Error:');
      air.trace(e);
    }
            
    return str;
  }
  
  function saveCurrentFile(){
    
    var f = air.File.applicationDirectory.resolvePath(outputFolder+"/"+currentFileName);
    saveFile(translated_text, f.nativePath);
    
    deleteCurrentFile();
    processNextFile();
  }
  
  function saveFile(content, filename){
    
    try {
      
      var file = new air.File(filename);
      var stream = new air.FileStream();
      stream.open(file, air.FileMode.WRITE);
      stream.writeUTFBytes(content);
      stream.close();
    
    } catch(e){
      air.trace('File Write Error:');
      air.trace(e);
      air.trace(e.message);
    }
    
  }
  
  // This is not working!
  // function moveCurrentFile(){
  //   
  //   try {
  //     
  //     var file = new air.File(filesList[currentFileIdx].nativePath);
  //     var target = air.File.applicationDirectory.resolvePath(finishedFolder+"/"+currentFileName);
  //     
  //     file.moveTo(target, true);
  //   
  //   } catch(e){
  //     air.trace('File Move Error:');
  //     air.trace(e);
  //   }
  //     
  // }
  
  function deleteCurrentFile(){
    
    try {
      
      var file = new air.File(filesList[currentFileIdx].nativePath);
      file.deleteFile();
    
    } catch(e){
      air.trace('File Delete Error:');
      air.trace(e);
    }
    
  }
  
  function processNextFile(){
    
    if(++currentFileIdx < filesList.length){
        
      currentFileName = filesList[currentFileIdx].name;
      
      log('Processing: ' + currentFileName);
      
      var content = readFile(filesList[currentFileIdx].nativePath);
      
      $('text-source').value = content;
      source_text = $('text-source').value; 
      
      runTranslation();
      
    } else {
      
      clearlog();
      
      var s = 'Translation complete.\n\n';
      s += 'Number of files translated: ' + filesList.length + '\n\n';
      s += 'Number of translation requests: ' + numTransReqs;
      
      $('text-log-overall').update(s);
      
    }
    
  }
  
</script>

</head>

<body>

<textarea id="text-source" wrap="off" style="display:none;"></textarea> 
<textarea id="text-log-overall"></textarea>
<textarea id="text-log" wrap="off"></textarea>

<br/><br/>

Text Extraction Method: 
<input type="radio" name="extract-method" id="extract-method-1" value="1" checked="checked" /> 
<label for="extract-method-1">Unicode</label>
<input type="radio" name="extract-method" id="extract-method-0" value="0" /> 
<label for="extract-method-0">CDATA</label>

<br/><br/>

<input id="input-run" type="button" value="Start Translating!" />

</body>
</html>
                                                     